package com.szwistar.common.comm.jsonrpc;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.szwistar.common.ERR;
import com.szwistar.common.comm.AsyncResult;
import com.szwistar.common.datastruct.JsonMapper;

/**
 * JSON-RPC 调用返回消息
 */
@JsonInclude(value=Include.NON_NULL)
public class JsonRpcMessageReturn extends JsonRpcMessage {
	// 错误码：不管返回结果是否正确，都会有错误码，正确的结果 errCode = 0
	protected int errCode = 0;
	public int getErrCode() { return errCode; }
	public void setErrCode(int errCode) { this.errCode = errCode; }

	// JSON 数据
	// 接收者应根据调用时的 JsonRpcMessageRequest 方法名来判断此字段中 JSON 对象类型，并进行解析
	protected String body = null;
	public String getBody() { return body; }
	public void setBody(String body) { this.body = body; }

	@Override
	public String toString() {
		String msg = "";
		if(body != null) { msg = (body.length() < 96) ? body : body.substring(0, 96) + " ..."; }
		return (errCode == 0) ?
				"JsonRpcMessageReturn.OK [msg='" + msg + "']" :
				"JsonRpcMessageReturn.ERROR(" + errCode + ") [msg='" + msg + "']";
	}

	protected JsonRpcMessageReturn() {
		super();
		this.msgType = MSG_RETURN;
	}

	protected JsonRpcMessageReturn(Long msgId, int errCode, String body) {
		this();
		if(body != null && body.length() > 10*1024) {
			LOG.warn("JsonRpc 试图传送大数据 {} bytes !", body.length());
		}
		this.msgId = (msgId != null) ? msgId : -1;
		this.errCode = errCode;
		this.body = body;
	}

	public static JsonRpcMessageReturn asyncResult(JsonRpcMessage request, AsyncResult<?> ret) throws Exception {
		// 如果返回的是异步结果，要等待返回？
		if(ret.isDone() || ret.waitReturn()) {
			if(ret.getErrCode() != 0) { return new JsonRpcMessageReturn(request.getMsgId(), ret.getErrCode(), ret.getMsg()); }
			return ok(request, ret.getResult());
		} else {
			return error(request, ERR.TIMEOUT, "API 调用超时！");
		}
	}

	public static JsonRpcMessageReturn error(JsonRpcMessage request, ERR err, String errMsg) {
		Long msgId = (request != null) ? request.getMsgId() : null;
		if(errMsg == null) { errMsg = err.msg(); }
		return new JsonRpcMessageReturn(msgId, err.code(), errMsg);
	}

	/**
	 * 创建一个返回消息
	 * @param request 用于取得其中的 msgId，返回消息的 msgId 与请求的要保持一致
	 * @param body 返回值参数，如果是字符串，则直接返回；否则会转换为 json 格式再返回
	 * @return 生成的返回消息
	 */
	public static JsonRpcMessageReturn ok(JsonRpcMessage request, Object body) {
		Long msgId = (request != null) ? request.getMsgId() : null;

		if(body instanceof String) {
			return new JsonRpcMessageReturn(msgId, 0, (String)body);
		}

		try {
			return new JsonRpcMessageReturn(msgId, 0, JsonMapper.toJson(body));
		} catch (Exception e) {
			return error(null, ERR.SYS, e.toString());
		}
	}

	/**
	 * 转发另一个返回消息，但要处理 msgId/from/to 字段
	 * @param request 用于取得其中的 msgId，返回消息的 msgId 与请求的要保持一致
	 * @param 要转发的消息
	 * @return 生成的返回消息
	 */
	public static JsonRpcMessageReturn forward(JsonRpcMessage request, JsonRpcMessageReturn another) {
		return new JsonRpcMessageReturn(request.getMsgId(), another.getErrCode(), another.getBody());
	}
}
